﻿using System;
using DataFiller.DataStorage.Extension.DataProvider;
using DataFiller.DataStorage.Interpreters;

namespace DataFiller.DataStorage.Extension.Interpreters
{
    internal enum ExtensionDirection
    {
        Horizontal,
        Vertical,
        None
    }

    /// <summary>
    /// for a excel template, get the evaluated value form the model with property path
    /// </summary>
    internal abstract class ExcelInterpreter : InterpreterBase
    {
        //protected PropertyPath _propertyPath;
        protected DataEvaluator _evaluator;
        protected ExtensionDirection Direction;
        protected string _propertyHolder;
        protected string _prefix;
        protected string _collectionSeperator;

        internal ExcelInterpreter()
        {
            //_propertyPath = new PropertyPath(string.Empty);
            _evaluator = new DataEvaluator();
        }

        #region base override
        protected override bool IsMatched(string placeholder)
        {
            bool result = base.IsMatched(placeholder);
            if (result)
            {
                _propertyHolder = PreMakePropertyPath(placeholder);
            }

            return result;
        }
        /// <summary>
        /// transform place holder into available property path
        /// </summary>
        protected virtual string PreMakePropertyPath(string placeholder)
        {
            string path = placeholder.Split
                (
                    new string[] { _prefix },
                    StringSplitOptions.RemoveEmptyEntries
                )[0];

            if (string.IsNullOrEmpty(path))
                throw new InvalidOperationException(string.Format("invalid place holder {0}, it should be {1}Collection&PropertyName", placeholder, _prefix));

            return path;
        }
        protected override object RetrieveCorrespondingData(object model)
        {
            _evaluator.SetEvaluator
                (
                    PreMakePropertyPath(_propertyHolder),
                    model,
                    _collectionSeperator,
                    null
                );

            return EncapsulateResult();
        }
        #endregion

        protected virtual DataEncapsulater EncapsulateResult()
        {
            DataEncapsulater result = new DataEncapsulater
            {
                Orientation = Direction,
                Data = _evaluator.EvaluatedValue
            };

            return result;
        }
    }
}
